#ifndef DHD_S_SVR
#define DHD_S_SVR 1

#include <map>
#include <string>
#include <boost/thread.hpp>

#include "socket_io.h"
#include "s_config.h"


namespace dhd
{
namespace server
{
      
   class Connection;
   class SRPDatabase;
   
   typedef boost::intrusive_ptr<Connection> PConnection;
   
   
   class InitializationError : public std::runtime_error
   {
     public:
       InitializationError( const std::string & what ) : std::runtime_error(what) {}
       ~InitializationError() throw() {}
   };
   
   
   class Server
   {
       typedef std::map< tcp::endpoint, PConnection > ConnMap;
       
       boost::asio::io_service    io_service;
       boost::asio::ssl::context *ssl_ctx;
       tcp::acceptor             *acceptor;
       
       boost::thread              inotify_thread;
       
       ConnMap                    conn_map;
       ServerConfig               conf;
       SRPDatabase               *srp_db;
       
       void inotify_thread_main();
       
     public:
       
       Server( const ServerConfig & _conf );
       
       ~Server();
       
       void async_accept_connection();
       
       void on_accept( tcp::socket * sock, tcp::endpoint * endpoint, const boost::system::error_code& error );
       
       void on_ssl_connect( tcp::socket *sock, tcp::endpoint *endpoint, ssl_socket * ssl_sock, const boost::system::error_code & error );
       
       void connection_closed( Connection * conn );
       
       bool authentication_required() { return srp_db != 0; }
       
       SRPDatabase * get_srp_db() { return srp_db; }
       
       const std::string & get_serv_root() { return conf.serv_dir; }
       
       void main();
   };
   
} // end namespace dhd::server
} // end namespace dhd

   
#endif